/**
 * @title DeFi借贷池演示脚本
 * @description 演示LendingPool合约的部署和主要功能交互
 * 包括：部署基础ERC20代币、部署借贷池、存款、添加抵押、借款和还款
 */
async function main() {
  console.log("=== DeFi借贷池演示流程 ===");
  
  /**
   * 第一步：准备账户和合约
   */
  console.log("\n1. 准备账户和环境");
  
  // 获取测试账户
  const [owner, borrower, lender] = await ethers.getSigners();
  console.log(`部署者账户: ${owner.address}`);
  console.log(`借款人账户: ${borrower.address}`);
  console.log(`存款人账户: ${lender.address}`);
  
  // 获取合约工厂
  const SimpleERC20 = await ethers.getContractFactory("SimpleERC20");
  const LendingPool = await ethers.getContractFactory("LendingPool");
  
  /**
   * 第二步：部署基础资产ERC20代币
   * LendingPool需要一个基础资产作为借贷标的
   */
  console.log("\n2. 部署基础资产代币");
  
  // 部署基础资产代币，初始供应量为1000000
  const underlyingToken = await SimpleERC20.deploy(1000000);
  await underlyingToken.deployed();
  console.log(`基础资产代币已部署到: ${underlyingToken.address}`);
  
  // 查询代币信息
  const tokenName = await underlyingToken.name();
  const tokenSymbol = await underlyingToken.symbol();
  const tokenDecimals = await underlyingToken.decimals();
  console.log(`基础资产: ${tokenName} (${tokenSymbol}), 精度: ${tokenDecimals}`);
  
  /**
   * 第三步：部署借贷池合约
   * 使用刚部署的ERC20代币作为基础资产
   */
  console.log("\n3. 部署借贷池合约");
  
  const lendingPool = await LendingPool.deploy(underlyingToken.address);
  await lendingPool.deployed();
  console.log(`借贷池合约已部署到: ${lendingPool.address}`);
  
  // 查询借贷池信息
  const aTokenName = await lendingPool.name();
  const aTokenSymbol = await lendingPool.symbol();
  const supplyAPY = await lendingPool.supplyAPY();
  const borrowAPY = await lendingPool.borrowAPY();
  const collateralFactor = await lendingPool.collateralFactor();
  
  console.log(`aToken名称: ${aTokenName}`);
  console.log(`aToken符号: ${aTokenSymbol}`);
  console.log(`存款年化收益率: ${supplyAPY}%`);
  console.log(`借款年化收益率: ${borrowAPY}%`);
  console.log(`抵押率: ${collateralFactor}%`);
  
  /**
   * 第四步：准备测试资金
   * 向借款人和存款人转账一些基础资产
   */
  console.log("\n4. 准备测试资金");
  
  // 转账给借款人
  const borrowerAmount = ethers.utils.parseUnits("500", tokenDecimals);
  await underlyingToken.transfer(borrower.address, borrowerAmount);
  console.log(`向借款人转账: ${ethers.utils.formatUnits(borrowerAmount, tokenDecimals)} ${tokenSymbol}`);
  
  // 转账给存款人
  const lenderAmount = ethers.utils.parseUnits("1000", tokenDecimals);
  await underlyingToken.transfer(lender.address, lenderAmount);
  console.log(`向存款人转账: ${ethers.utils.formatUnits(lenderAmount, tokenDecimals)} ${tokenSymbol}`);
  
  /**
   * 第五步：存款演示
   * 存款人将资金存入借贷池，获得aToken
   */
  console.log("\n5. 存款演示");
  
  // 存款人授权借贷池使用其代币
  await underlyingToken.connect(lender).approve(lendingPool.address, lenderAmount);
  console.log(`存款人授权借贷池使用其代币`);
  
  // 存款人存款
  const depositAmount = ethers.utils.parseUnits("800", tokenDecimals);
  await lendingPool.connect(lender).deposit(depositAmount);
  console.log(`存款人存入: ${ethers.utils.formatUnits(depositAmount, tokenDecimals)} ${tokenSymbol}`);
  
  // 查询存款人持有的aToken数量
  const aTokenBalance = await lendingPool.balanceOf(lender.address);
  console.log(`存款人获得aToken数量: ${ethers.utils.formatUnits(aTokenBalance, tokenDecimals)} ${aTokenSymbol}`);
  
  /**
   * 第六步：借款人操作
   * 1. 先存入一部分代币作为抵押
   * 2. 然后进行借款
   */
  console.log("\n6. 借款人操作演示");
  
  // 借款人授权借贷池使用其代币
  await underlyingToken.connect(borrower).approve(lendingPool.address, borrowerAmount);
  console.log(`借款人授权借贷池使用其代币`);
  
  // 借款人存款（为了获取aToken用于抵押）
  const borrowerDepositAmount = ethers.utils.parseUnits("300", tokenDecimals);
  await lendingPool.connect(borrower).deposit(borrowerDepositAmount);
  console.log(`借款人存入: ${ethers.utils.formatUnits(borrowerDepositAmount, tokenDecimals)} ${tokenSymbol}`);
  
  // 借款人添加抵押
  const collateralAmount = ethers.utils.parseUnits("250", tokenDecimals);
  await lendingPool.connect(borrower).addCollateral(collateralAmount);
  console.log(`借款人添加抵押: ${ethers.utils.formatUnits(collateralAmount, tokenDecimals)} ${aTokenSymbol}`);
  
  // 查询借款人的抵押金额
  const borrowerCollateral = await lendingPool.collateralAmount(borrower.address);
  console.log(`借款人抵押金额: ${ethers.utils.formatUnits(borrowerCollateral, tokenDecimals)} ${aTokenSymbol}`);
  
  // 借款人借款
  const borrowAmount = ethers.utils.parseUnits("150", tokenDecimals);
  await lendingPool.connect(borrower).borrow(borrowAmount);
  console.log(`借款人借款: ${ethers.utils.formatUnits(borrowAmount, tokenDecimals)} ${tokenSymbol}`);
  
  // 查询借款人借款余额
  const borrowerBorrowBalance = await lendingPool.borrowBalance(borrower.address);
  console.log(`借款人借款余额: ${ethers.utils.formatUnits(borrowerBorrowBalance, tokenDecimals)} ${tokenSymbol}`);
  
  // 查询借款人基础资产余额
  const borrowerUnderlyingBalance = await underlyingToken.balanceOf(borrower.address);
  console.log(`借款人基础资产余额: ${ethers.utils.formatUnits(borrowerUnderlyingBalance, tokenDecimals)} ${tokenSymbol}`);
  
  /**
   * 第七步：还款演示
   * 借款人偿还借款
   */
  console.log("\n7. 还款演示");
  
  // 借款人授权还款金额
  await underlyingToken.connect(borrower).approve(lendingPool.address, borrowAmount);
  
  // 借款人还款
  await lendingPool.connect(borrower).repay(borrowAmount);
  console.log(`借款人还款: ${ethers.utils.formatUnits(borrowAmount, tokenDecimals)} ${tokenSymbol}`);
  
  // 查询还款后借款余额
  const newBorrowBalance = await lendingPool.borrowBalance(borrower.address);
  console.log(`还款后借款余额: ${ethers.utils.formatUnits(newBorrowBalance, tokenDecimals)} ${tokenSymbol}`);
  
  /**
   * 第八步：移除抵押和提款演示
   */
  console.log("\n8. 移除抵押和提款演示");
  
  // 借款人移除部分抵押
  await lendingPool.connect(borrower).removeCollateral(collateralAmount);
  console.log(`借款人移除抵押: ${ethers.utils.formatUnits(collateralAmount, tokenDecimals)} ${aTokenSymbol}`);
  
  // 借款人提款
  await lendingPool.connect(borrower).withdraw(borrowerDepositAmount);
  console.log(`借款人提款: ${ethers.utils.formatUnits(borrowerDepositAmount, tokenDecimals)} ${tokenSymbol}`);
  
  // 存款人提款
  await lendingPool.connect(lender).withdraw(depositAmount);
  console.log(`存款人提款: ${ethers.utils.formatUnits(depositAmount, tokenDecimals)} ${tokenSymbol}`);
  
  console.log("\n=== DeFi借贷池演示完成 ===");
}

// 执行主函数
main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error("演示过程中发生错误:", error);
    process.exit(1);
  });